import os
import sys
import traceback
import json

from flask import Flask, jsonify
from flask_cors import CORS
from dotenv import load_dotenv
from werkzeug.exceptions import HTTPException

from app.utils.logger import logger
from app.utils.exceptions import AppException


def create_app(config_name):
    # create and configure the app
    app = Flask(__name__)
    CORS(app, expose_headers=['Content-Disposition'], resources={r"/*": {"origins": "http://localhost:5173"}})
    load_dotenv()

    # 核心配置逻辑
    is_dev_mode = config_name == "dev" if config_name else os.getenv("FLASK_ENV") == "dev"

    # 配置 Flask Debug 模式
    app.config["DEBUG"] = is_dev_mode

    app.json.ensure_ascii = False

    # 非开发环境禁用 print 输出
    if not is_dev_mode:
        sys.stdout = open(os.devnull, "w")  # 重定向标准输出到空设备

    @app.route("/health", methods=["GET"])
    def health():
        return jsonify({
            "status": "ok"
        })

    try:
        from app.blueprints import course_blueprint, user_blueprint, material_blueprint, \
             department_blueprint, classes_blueprint

        app.register_blueprint(course_blueprint.course)
        app.register_blueprint(user_blueprint.user)
        app.register_blueprint(material_blueprint.material)
        app.register_blueprint(department_blueprint.department)
        app.register_blueprint(classes_blueprint.classes)

    except AppException as appE:
        appE.log(logger)
        sys.exit(1)

    @app.errorhandler(Exception)
    def handle_all_exceptions(e):
        print(isinstance(e, AppException))
        # 处理自定义异常
        if isinstance(e, AppException):
            e.log(logger)  # 记录日志
            return e.to_response()

        # 拦截所有 Werkzeug HTTP 异常
        if isinstance(e, HTTPException):
            return jsonify(
                error_code=f"HTTP_{e.code}",
                message=e.description,
            ), e.code

        # 处理其他未捕获异常
        tb = traceback.extract_tb(e.__traceback__)[-1]  # 获取最底层堆栈
        error_file = tb.filename.split("/")[-1]  # 取文件名
        error_line = tb.lineno

        logger.error(f"[{error_file}:{error_line}]未处理的异常: {str(e).replace('{', '{{').replace('}', '}}')}\n"
                     f"原始异常: {str(e.__cause__) if e.__cause__ else '无'}\n", exc_info=True)
        return jsonify({
            "error_code": "UNKNOWN_ERROR",
            "message": "系统发生未知错误"
        }), 500

    logger.info(f"Flask应用已启动")

    return app
